#!/usr/bin/env guile
!#
(use-modules (ice-9 rdelim))

(define (parse-line line)
  (let* ((space (or (string-index line char-whitespace?)
                    (string-length line)))
         (header (string-trim-both line
                                   (char-set-union char-set:whitespace
                                                   char-set:punctuation)
                                   0 space))
         (val (string->number (string-trim-both (substring line space)))))
    (values header val)))

(define (scan-for-headers headers-to-omit port)
  (define (finish headers row)
    (values (map (lambda (h r) (and r h))
                 headers row)
            (filter values row)))
  (let lp ((headers '()) (row '()))
    (let ((line (read-line port)))
      (if (eof-object? line)
          (finish (reverse headers) (reverse row))
          (call-with-values (lambda () (parse-line line))
            (lambda (header val)
              (if (member header headers)
                  (begin
                    (unread-string (string-append line "\n") port)
                    (finish (reverse headers) (reverse row)))
                  (lp (cons header headers)
                      (cons (and (not (member header headers-to-omit)) val)
                            row)))))))))

(define *delim* #\tab)

(define (quote-string s)
  (if (string-index s *delim*)
      (error "implement me")
      s))

(define (write-headers headers port)
  (display (string-join (map quote-string (filter values headers))
                        (string *delim*))
           port)
  (newline port))

(define (write-row row port)
  (display (string-join (map number->string row)
                        (string *delim*))
           port)
  (newline port))

(define (read-row headers port)
  (let lp ((headers headers) (row '()))
    (if (null? headers)
        (reverse row)
        (let ((line (read-line port)))
          (if (eof-object? line)
              line
              (lp (cdr headers)
                  (if (car headers)
                      (cons (string->number
                             (string-trim-both
                              (substring line
                                         (string-index line char-whitespace?))))
                            row)
                      row)))))))

(define (bench-to-csv headers-to-omit in out)
  (call-with-values (lambda ()
                      (scan-for-headers headers-to-omit in))
    (lambda (headers row)
      (write-headers headers out)
      (let lp ((row row))
        (unless (eof-object? row)
          (write-row row out)
          (lp (read-row headers in)))))))

(define (main headers-to-omit)
  (bench-to-csv headers-to-omit
                (current-input-port) (current-output-port)))

(main (cdr (command-line)))
